#include "StdAfx.h"
#include "MenuCH.h"


int strcfind(LPTSTR string, TCHAR ch,int nStart)
{
	int i=nStart;
   
	while( i < lstrlen(string) )
	{
		if( *(string+i) == ch )
			return i;
		i++;
	}
	return -1;
}
CMenuCH::CMenuCH()
{
	pDC = NULL;
 
}
CMenuCH::~CMenuCH()
{
	while( m_MenuList.GetCount() )	// release all menu item
	{
		CMenuItem* pItem = m_MenuList.GetHead();
		if( pItem->m_pszHotkey != NULL )
			delete pItem->m_pszHotkey;
		delete pItem->m_pBitmap;	// the menu include bitmap
		delete pItem;
		m_MenuList.RemoveHead();
	}
}
BOOL CMenuCH::AppendMenu(UINT nFlags,UINT nIDNewItem,LPTSTR lpszNewItem,
						 UINT nIDBitmap,HICON hIcon)
{
	CBitmap* pBitmap;

	if( nIDBitmap != NULL )				 // the menu has bitmap
	{
		pBitmap = new CBitmap;			 
		pBitmap->LoadBitmap(nIDBitmap);  // load bitmap from application resource
	}
	else
		pBitmap = NULL;					 // not has bitmap 

	// create a new menu item that associated bitmap and icon (if has)
	CMenuItem* pItem = new CMenuItem(lpszNewItem,pBitmap,hIcon);
	m_MenuList.AddTail(pItem);

	pItem->m_nHeight = 0;	// set current menu height
	pItem->m_nWidth  = 0;		// set current menu width
	if( !(nFlags & MF_POPUP) )		// not handled popup menu
		nFlags |= MF_OWNERDRAW;
	

	lstrcpy(pItem->m_szText,_T(""));
	pItem->m_pszHotkey = NULL;
	int n;
  if( (n=strcfind(lpszNewItem,_T('\t'),0)) != -1 )	// get item string and hotkey string
	{
		_tcsnccpy(pItem->m_szText,lpszNewItem,n);
		pItem->m_szText[n] = _T('\0');

		pItem->m_pszHotkey = new TCHAR[lpszNewItem+n+1,lstrlen(lpszNewItem)-(n+1)+1+1];
		_tcsnccpy(pItem->m_pszHotkey,lpszNewItem+n+1,lstrlen(lpszNewItem)-(n+1)+1);
		pItem->m_pszHotkey[lstrlen(lpszNewItem)-(n+1)+1] = _T('\0');
	}	
	else 
		lstrcpy(pItem->m_szText,lpszNewItem);
	return CMenu::AppendMenu(nFlags,nIDNewItem,(LPCTSTR)pItem);
}


void CMenuCH::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
{

  UINT state = GetMenuState(lpMIS->itemID,MF_BYCOMMAND);

	CMenuItem* pItem = reinterpret_cast<CMenuItem *>(lpMIS->itemData);

  
	CString text(pItem->m_szText);
  text +=  pItem->m_pszHotkey;
  CDC *pDC = AfxGetMainWnd()->GetDC();							
 // pDC->SelectObject(&font);	
  CSize size = pDC->GetTextExtent(text);
 
  size.cx += 23;
  size.cy += 5;
  
  if(pItem->m_nWidth < size.cx )  pItem->m_nWidth = size.cx;
  lpMIS->itemWidth =  pItem->m_nWidth;

  
  if( state & MF_SEPARATOR ) {
    lpMIS->itemHeight = 6;		// item state is separator
    return;
  }
  
  
  if(pItem->m_nHeight < size.cy) pItem->m_nHeight =  size.cy;
  lpMIS->itemHeight = pItem->m_nHeight;



}

void CMenuCH::DrawXPMenu(LPDRAWITEMSTRUCT lpDIS)
{
  
	pDC = CDC::FromHandle(lpDIS->hDC);

//  pDC->SelectObject(&font);

  
   
	CMenuItem* pItem = reinterpret_cast<CMenuItem *>(lpDIS->itemData);
  CRect rectFull(&lpDIS->rcItem); 
   
  // get icon region and text region
	CRect rectIcon(rectFull.left,rectFull.top,rectFull.left+20,rectFull.top+20);
	CRect rectText(rectIcon.right,rectFull.top,rectFull.right,rectFull.bottom);

	UINT state = GetMenuState(lpDIS->itemID,MF_BYCOMMAND);

	if (lpDIS->itemAction & ODA_DRAWENTIRE)
	{
		// paint the brush and icon item in requested
		CRect rect;
		// paint item background 
		pDC->FillRect(rectFull,&CBrush(GetSysColor(COLOR_MENU)));
		pDC->FillRect(rectIcon,&CBrush(GetSysColor(COLOR_MENU)));

		if( state & MF_SEPARATOR )	// item is separator
		{	// draw a etched edge
			rect.CopyRect(rectText);
			rect.OffsetRect(5,3);
      rect.left = rectIcon.left;
			pDC->DrawEdge(rect,EDGE_ETCHED,BF_TOP);
		}
			
		if( state & MFS_CHECKED ) // item has been checked
		{
			// paint the frame and brush,then draw a check mark
			rect.CopyRect(rectIcon);
			rect.DeflateRect(1,1,1,1);
			pDC->FrameRect(rect,&CBrush(RGB(64,64,128)));

			rect.DeflateRect(1,1,1,1);
			pDC->FillRect(rect,&CBrush(RGB(216,216,225)));
			DrawCheckMark(pDC,rect.left+5,rect.top+5,RGB(0,0,0));
		}
		if( pItem->m_pBitmap )	// item has bitmap
		{	// draw a bitmap
			CDC memDC;
			memDC.CreateCompatibleDC(pDC);
			CBitmap* pOldBitmap = memDC.SelectObject(pItem->m_pBitmap);
	//		pDC->BitBlt(rectIcon.left+2,rectIcon.top+2,16,16,&memDC,0,0,SRCCOPY);
         pDC->TransparentBlt(rectIcon.left + 2,rectIcon.top + 2,16,16,&memDC,0,0,16,16,RGB(255,0,255));
			memDC.SelectObject(pOldBitmap);
		}

		// draw display text
    
		pDC->SetBkMode(TRANSPARENT);
		rect.CopyRect(rectText);
		rect.DeflateRect(2,2,2,2);
		rect.OffsetRect(6,2);
		if( state & MFS_DISABLED )	// item has been disabled
			pDC->SetTextColor(GetSysColor(COLOR_MENUTEXT));



	
		pDC->DrawText(pItem->m_szText,lstrlen(pItem->m_szText),rect,DT_LEFT|DT_SINGLELINE);	
		if( pItem->m_pszHotkey != NULL )
		pDC->DrawText(pItem->m_pszHotkey,lstrlen(pItem->m_pszHotkey),
					  CRect(rect.right-60,rect.top,rect.right,rect.bottom),DT_LEFT|DT_SINGLELINE);	
	}

	if ((lpDIS->itemState & ODS_SELECTED) &&
		(lpDIS->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)))
	{
		// item has been selected
		CRect  rect;

		// item has bitmap - draw a raised edge
		//if( !(state & MFS_CHECKED ) && (pItem->m_pBitmap != NULL) )	
			//pDC->DrawEdge(rectIcon,EDGE_RAISED,BF_RECT);

		// draw hilite frame
		rect.SetRect(rectText.left+2,rectText.top,rectText.right,rectText.bottom);
		pDC->FrameRect(rect,&CBrush(RGB(64,64,128)));
		// draw hilite brush
		rect.DeflateRect(1,1,1,1);
		pDC->FillRect(rect,&CBrush(RGB(216,216,225)));
		// draw display text
		rect.CopyRect(rectText);
		rect.DeflateRect(2,2,2,2);
		rect.OffsetRect(6,2);

		pDC->SetBkMode(TRANSPARENT);
		pDC->DrawText(pItem->m_szText,lstrlen(pItem->m_szText),rect,DT_LEFT|DT_SINGLELINE);	
		if( pItem->m_pszHotkey != NULL )
		pDC->DrawText(pItem->m_pszHotkey,lstrlen(pItem->m_pszHotkey),
					  CRect(rect.right-60,rect.top,rect.right,rect.bottom),DT_LEFT|DT_SINGLELINE);	
		m_curSel = lpDIS->itemID;	// get current selected
	}
  

	if (!(lpDIS->itemState & ODS_SELECTED) &&
		(lpDIS->itemAction & ODA_SELECT))
	{
		// item has been de-selected
		CRect rect;
		rect.CopyRect(rectIcon);

		if( pItem->m_pBitmap )
		{	// the item has bitmap - repaint icon region and bitmap
			pDC->FillRect(rect,&CBrush(GetSysColor(COLOR_MENU)));
			CDC memDC;
			memDC.CreateCompatibleDC(pDC);
			CBitmap* pOldBitmap = memDC.SelectObject(pItem->m_pBitmap);
		//	pDC->BitBlt(rectIcon.left+2,rectIcon.top+2,16,16,&memDC,0,0,SRCCOPY);

      pDC->TransparentBlt(rectIcon.left + 2,rectIcon.top + 2,16,16,&memDC,0,0,16,16,RGB(255,0,255));

			memDC.SelectObject(pOldBitmap);
		}

		// draw display text
		pDC->FillRect(rectText,&CBrush(GetSysColor(COLOR_MENU)));
		rect.CopyRect(rectText);
		rect.DeflateRect(2,2,2,2);
		rect.OffsetRect(6,2);
		pDC->SetBkMode(TRANSPARENT);
		if( state & MFS_DISABLED ) // item has been disabled
			pDC->SetTextColor(COLOR_MENUTEXT);

		pDC->DrawText(pItem->m_szText,lstrlen(pItem->m_szText),rect,DT_LEFT|DT_SINGLELINE);	
		if( pItem->m_pszHotkey != NULL )
		pDC->DrawText(pItem->m_pszHotkey,lstrlen(pItem->m_pszHotkey),
					  CRect(rect.right-60,rect.top,rect.right,rect.bottom),DT_LEFT|DT_SINGLELINE);	
	}
}
void CMenuCH::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
  DrawXPMenu(lpDIS);
}

void CMenuCH::DrawCheckMark(CDC* pDC,int x,int y,COLORREF color)
{
	CPen Pen;

	Pen.CreatePen(PS_SOLID,0,color);
	CPen *pOldPen = pDC->SelectObject(&Pen);
	
	pDC->MoveTo(x,y+2);
	pDC->LineTo(x,y+5);
	
	pDC->MoveTo(x+1,y+3);
	pDC->LineTo(x+1,y+6);
	
	pDC->MoveTo(x+2,y+4);
	pDC->LineTo(x+2,y+7);
	
	pDC->MoveTo(x+3,y+3);
	pDC->LineTo(x+3,y+6);
	
	pDC->MoveTo(x+4,y+2);
	pDC->LineTo(x+4,y+5);
	
	pDC->MoveTo(x+5,y+1);
	pDC->LineTo(x+5,y+4);
	
	pDC->MoveTo(x+6,y);
	pDC->LineTo(x+6,y+3);
	
	pDC->SelectObject(pOldPen);
	Pen.DeleteObject();
}

